home *** CD-ROM | disk | FTP | other *** search
- /*
- * Middleman.c - Examples of processing/issuing requests.
- *
- * Mark D. Rustad. 6/8/90.
- *
- * Note that this file will not compile and run, it is just excerpts. Not only
- * that, but it doesn't really do anything, even if it could run. It does
- * show a few techniques that are commonly used with A/ROSE.
- *
- * Also note that in this context "zip" simply means "nothing" (Any thought of
- * of "zone information protocol" should be suppressed). This also describes
- * what this "middleman" does, nothing. Presumably, most of the time, such
- * tasks would actually do some useful work....
- */
-
- #include <clister.h>
- #include <os.h>
- #include "FunMacros.h"
-
- _TITLE("Middleman.c - Examples of processing/issuing requests.")
- _SPACE("4,20,Definitions")
- /*
- * Definitions.
- */
-
- /* mCodes */
-
- #define ZZDoZip 0x422 /* mCode for doing zip asynchronously */
- #define ZZDontZip 0x424 /* mCode for not doing zip asynchronously */
- #define ZZSyncZip 0x426 /* mCode for doing zip synchronously */
-
- /* Error codes */
-
- #define EEBadCode 0x27 /* mStatus return for bad mCode */
- #define EENoResources 0x28 /* mStatus return for no resources to do request */
-
- typedef void (*funcPtr)();
-
- _SPACE("4,20,Globals")
- /*
- * Global Data.
- */
-
- tid_type NextServerTID; // This gets set somehow
- tid_type MyTID; // Likewise
-
- _SPACE("4,20,Main")
- /*
- * Main - Here be the main loop.
- */
-
- Main()
- {
- register AROSEmessage *mp;
-
- initialize(); // There's always lots of this, right?
-
- for (;;)
- {
- mp = Receive(0, 0, 0, 0);
-
- /* This checks for completions from the next server. This approach
- * assumes that the next server does not make requests to us, but
- * only replies. Checks could be made on mCode.
- */
-
- if (mp->mFrom == NextServerTID)
- {
- ((funcPtr)mp->mSData[0])(mp); // Call routine to complete request
- continue; // Back up to the top of the for loop
- }
-
- switch (mp->mCode)
- {
- case ZZDoZip: // Start doing zip asynchronously here
- StartZipping(mp);
- break;
-
- case ZZDontZip: // Start not doing zip asynchronously here
- StartNotZipping(mp);
- break;
-
- case ZZSyncZip: // Start doing zip synchronously here
- StartSyncZipping(mp);
- break;
-
- default: // Got a bad mCode
- if (mp->mCode & 0x8001) // If a reply or undeliverable
- {
- FreeMsg(mp); // Just throw it away
- }
- else
- {
- Reply(mp, EEBadCode);
- }
- }
- }
- }
-
- _SPACE("4,20,StartZipping")
- /*
- * StartZipping - Begin asynchronous zip processing.
- *
- * This routine demonstrates one strategy for handling asynchronous requests.
- *
- * Inputs:
- * mp - Points to request message.
- */
-
- void StartZipping(AROSEmessage *mp)
- {
- register AROSEmessage *cmp;
- void CompleteZipping(AROSEmessage *mp);
-
- if ((cmp = GetMsg()) == 0)
- {
- /* Deal with lack of messages somehow. Perhaps maintain an internal
- * queue of requests that had to be deferred (note that if things must
- * be done in order, you'll have to queue all incoming requests to the
- * queue (FIFO) whenever anything is on the queue).
- *
- * Many times, a task like this would preallocate a few message
- * buffers during initialization and keep them in a list. Whenever
- * the list was empty, the task would either try to do a GetMsg or
- * would simply queue the request and wait for the completions to
- * come back. Those completion message buffers would then be reused
- * to issue new requests.
- */
-
- Reply(mp, EENoResources); // We cop out here...
- return;
- }
-
- cmp->mTo = NextServerTID;
- cmp->mCode = NSCode; // mCode for next server's request
- cmp->mSData[0] = (long)CompleteZipping; // Points to completion routine
- cmp->mSData[1] = (long)mp; // Save pointer to client's request being processed
- cmp->mOData[0] = 100214; // Hypothetical data for hypothetical server
- Send(cmp);
- }
-
- _SPACE("4,20,CompleteZipping")
- /*
- * CompleteZipping - Complete asynchronous zip request.
- *
- * Inputs:
- * mp - Points to completion message.
- */
-
- void CompleteZipping(register AROSEmessage *mp);
- {
- register AROSEmessage *ump; /* User's message pointer */
-
- ump = (AROSEmessage *)mp->mSData[1];
- Reply(ump, mp->mStatus); /* Reply to user's message */
- FreeMsg(mp); /* Free the reply to our request */
- }
-
- _SPACE("4,20,StartNotZipping")
- /*
- * StartNotZipping - Start not doing zip asynchronously.
- *
- * This routine demonstrates a forwarding method that can sometimes be used.
- *
- * Inputs:
- * mp - Points to request message.
- */
-
- void StartNotZipping(AROSEmessage *mp)
- {
- /*
- * Note that this technique assumes that either no reply will be sent to the
- * user, or that the user will not care that the mFrom is not where he sent
- * the original request. It also assumes that the mCodes just "happened" to
- * be the same. In other cases, if mOData is not used by in the request, this
- * intermediary may save mFrom in mOData, change mFrom and forward the request,
- * then catch the reply and undo the changes later.
- */
-
- mp->mTo = NextServerTID; // Just forward it on
- mp->mOData[2] = 12; // Maybe add a little info
- Send(mp);
- }
-
- _SPACE("4,20,StartSyncZipping")
- /*
- * StartSyncZipping - Start doing zip synchronously.
- *
- * This routine demonstrates handling a synchronous request. It uses a
- * sleazy trick to avoid the case of not having a message buffer available.
- * Since you probably went to MacHack to learn sleazy tricks, it is included
- * here to satisfy your lust for sleazy tricks.
- */
-
- void StartSyncZipping(register AROSEmessage *mp)
- {
- long id;
- AROSEmessage tmp; // NOTE - NOT a pointer!
-
- /*
- * The following line saves the original request message on the stack, so
- * we can use that message buffer to make the synchronous request. Of
- * course, you could add logic to only do the copying if no messages were
- * available, but this example doesn't to keep things simple.
- */
-
- tmp = *mp; // Save original request on stack!
-
- mp->mTo = NextServerTID; // Set up request to next server
- mp->mFrom = MyTID;
- mp->mCode = NextServermCodeValue;
- id = mp->mId;
- Send(mp);
-
- mp = Receive(id, 0, 0, 0); // Wait for completion
-
- id = mp->mStatus; // Save status
-
- *mp = tmp; // Restore original request!
-
- Reply(mp, id); // Send reply to original request
- }
-
- /* End of Middleman.c */
-